feat: add two-layer duplicate code detection to PR check (#42)#46
Conversation
Adds DUPLICATE_MIN_LINES (5), DUPLICATE_MIN_TOKENS (50), DUPLICATE_IGNORE_PATTERNS ([]), and DUPLICATE_SCAN_PATHS ([]) to CONFIG. All four keys are configurable so teams using this on other repos can tune thresholds without touching library code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Layer 1 static duplicate detection: runs jscpd via child_process,
reads the JSON report it writes to a temp dir, and returns a structured
array of {firstFile, secondFile, lines, tokens}. Returns empty array on
empty input, missing report file, or non-zero jscpd exit — no throws.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parses require()/import statements in JS/TS files, resolves relative paths to absolute, and returns the union of changed files plus their direct local imports. Non-JS files are passed through without parsing; files not on disk and external/node_modules imports are skipped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds analyzeDuplicatesWithClaude(client, filePaths, staticFindings) which reads file contents, passes them to Claude with a duplication- focused system prompt, and returns structured findings with file1/file2/ similarity/concern/confidence. Degrades to [] when client is null or the API response is malformed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs runDuplicateCheck against PR production files after checkout. Adds a 'Duplicate Code' section to the PR comment when findings exist, showing file:start-end pairs with line/token counts (capped at 10). Section is omitted silently when jscpd finds no duplicates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Layer 2 semantic duplicate detection when ANTHROPIC_API_KEY is set. Uses resolveModuleNeighbors to scope analysis to changed files plus their direct imports, then passes results to analyzeDuplicatesWithClaude. PR comment Duplication section now shows static findings, semantic findings (when found), and a layer indicator confirming which layers ran. Degrades to Layer 1 only when API key is absent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…set.sh Uses PDCA_SKILL_DIR environment variable instead of an absolute path, with a guard that warns and skips the install if the directory is absent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds four DUPLICATE_* keys to the configuration table with defaults and descriptions. Includes a tuning guide with example overrides for Java, Python, and Go repos where boilerplate inflates false positives. Updates the pr-metrics.yml architecture description to reflect the lib/duplicate.js and lib/claude.js dependencies added in this cycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PR AnalysisSize: large (based on production code) Concerns
Strengths
Commit AnalysisTotal Commits: 9
Commit Detailsc33afd6 Ken Judy (6/9/2026) 9bce469 Ken Judy (6/9/2026) ebc9063 Ken Judy (6/12/2026) bf1eac4 Ken Judy (6/12/2026) 13e2db9 Ken Judy (6/12/2026) 23664a6 Ken Judy (6/12/2026) d320a65 Ken Judy (6/12/2026) d601314 Ken Judy (6/12/2026) d5d839c Ken Judy (6/12/2026) Test CoverageTest Adequacy: good
Target ratio: 0.5-2.0 test lines per production line DORA Capability AssessmentArchetype: mixed-signals
Duplicate CodeFound 1 duplicate block(s) across the changed files:
|
Summary
## Duplicate Codesection in the PR comment when findings existANTHROPIC_API_KEY): scopes analysis to changed files plus their direct module neighbors, finds structural similarity that token-level matching misseslib/config.jsso teams using this on other repos (Java, Python, Go) can tune without touching library codeNew files
lib/duplicate.js—runDuplicateCheck(filePaths)andresolveModuleNeighbors(filePaths)__tests__/duplicate.test.js— 9 tests covering both functions__tests__/config.test.js— 4 tests for new config key defaultsChanged files
lib/claude.js— addsanalyzeDuplicatesWithClaude(client, filePaths, staticFindings)lib/config.js— addsDUPLICATE_MIN_LINES,DUPLICATE_MIN_TOKENS,DUPLICATE_IGNORE_PATTERNS,DUPLICATE_SCAN_PATHS.github/workflows/pr-metrics.yml— integrates both layers; PR comment shows static findings, semantic findings, and a layer indicatorCLAUDE.md— documents the four config keys; includes threshold tuning examples for Java, Python, and GoTest plan
ANTHROPIC_API_KEYcheckrunDuplicateCheck([])returns[]without calling jscpdresolveModuleNeighborsskips non-JS files, deleted files, and external importsanalyzeDuplicatesWithClaude(null, ...)returns[]without calling the API🤖 Generated with Claude Code